#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <left4dhooks>


#define PLUGIN_VERSION "1.0"


public Plugin myinfo =
{
	name = "l4d2_team3_protector",
	author = "豆瓣酱な",
	description = "拦截特感对队友/小僵尸/女巫的伤害.",
	version = PLUGIN_VERSION,
	url = "https://gitee.com/sweet-and-sour-bombs/adfvsdsd"
};



public void OnPluginStart()
{
	// 挂钩所有玩家
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientInGame(i))
		{
			OnClientPutInServer(i);
		}
	}
    
	// 挂钩地图上已有的小僵尸和女巫
	HookExistingEntities();
}

public void OnClientPutInServer(int client)
{
	SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}

public void OnEntityCreated(int entity, const char[] classname)
{
	// 动态挂钩新生成的小僵尸和女巫
	if (StrEqual(classname, "infected") || StrEqual(classname, "witch"))
	{
		SDKHook(entity, SDKHook_OnTakeDamage, OnTakeDamage);
	}
}

public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype)
{
	// 仅处理特感(Team 3)造成的伤害
	if (IsValidClient(attacker) && GetClientTeam(attacker) == 3)
	{
		// 检查受害者类型
		bool isSITeam = IsValidClient(victim) && GetClientTeam(victim) == 3;
		bool isCommon = IsCommonInfected(victim);
		bool isWitch = IsWitch(victim);
        
		if (isSITeam || isCommon || isWitch)
		{
			char weapon[64];
			GetAttackWeapon(attacker, inflictor, weapon, sizeof(weapon));
            
			// 拦截特感爪击(*_claw)，但排除Tank石头(tank_rock)
			if (StrContains(weapon, "_claw") != -1 && !StrEqual(weapon, "tank_rock"))
			{
				damage = 0.0;
				return Plugin_Changed;
			}
		}
	}
	return Plugin_Continue;
}

// 获取攻击武器
void GetAttackWeapon(int attacker, int inflictor, char[] buffer, int maxlength)
{
	if (IsValidEntity(inflictor))
	{
		GetEntityClassname(inflictor, buffer, maxlength);
	}
	else
	{
		GetClientWeapon(attacker, buffer, maxlength);
	}
}

// 挂钩现有实体
void HookExistingEntities()
{
	int entity = -1;
	while ((entity = FindEntityByClassname(entity, "infected")) != -1)
	{
		if (IsValidEntity(entity)) SDKHook(entity, SDKHook_OnTakeDamage, OnTakeDamage);
	}
    
	entity = -1;
	while ((entity = FindEntityByClassname(entity, "witch")) != -1)
	{
		if (IsValidEntity(entity)) SDKHook(entity, SDKHook_OnTakeDamage, OnTakeDamage);
	}
}

// 检查是否是小僵尸
bool IsCommonInfected(int entity)
{
	if (!IsValidEntity(entity)) return false;
    
	char classname[64];
	GetEntityClassname(entity, classname, sizeof(classname));
	return StrEqual(classname, "infected");
}

// 检查是否是女巫
bool IsWitch(int entity)
{
	if (!IsValidEntity(entity)) return false;
    
	char classname[64];
	GetEntityClassname(entity, classname, sizeof(classname));
	return StrEqual(classname, "witch");
}

// 检查是否是有效玩家
bool IsValidClient(int client)
{
	return (client > 0 && client <= MaxClients && IsClientInGame(client));
}